import { _decorator, Component, } from 'cc';
import Instance from "../../../Core/Utils/Instance";
import EventMgr from '../../../Core/Event/EventMgr';
import IScene from './IScene';
import { SceneState } from './SceneState';
import { SceneManagerEvent } from './SceneManagerEvent';
/**场景管理器 */
export default class SceneManager extends Component {
    private _scenes: Object;
    private _currentScene: IScene;
    private _nextScene: IScene;
    public static get ins(): SceneManager {
        return Instance.get(SceneManager);
    }
    constructor() {
        super();
        this._scenes = {};
    }
    public registerScene(scene: IScene): void {
        if (this._scenes[scene.sceneName] == null) {
            scene.enterCallback = (scene: IScene) => {
                this.onSceneEntered(scene);
            };
            scene.exitCallback = (scene: IScene) => {
                this.onSceneExited(scene);
            };
            this._scenes[scene.sceneName] = scene;
        }
    }

    /**
     * 注销场景
     */
    public unregisterScene(scene: IScene): void {
        delete this._scenes[scene.sceneName];
    }
    /**
     * 进入场景
     */
    public enterScene(scene: IScene): void {
        // 不能重复进入同一场景
        if (this._currentScene != null && this._currentScene.sceneName == scene.sceneName) {
            return;
        }
        // 下一场景进入中不能进入场景
        if (this._nextScene != null && this._nextScene.state == SceneState.ENTERING) {
            return;
        }
        this._nextScene = scene;
        // 退出当前场景
        if (this._currentScene == null) {
            this.enterNextScene();
        } else {
            this.exitCurrentScene();
        }
    }
    /**
     * 退出当前场景
     */
    private exitCurrentScene(): void {
        if (this._currentScene.state == SceneState.RUNNING) {
            this._currentScene.state = SceneState.EXITING;
            this._currentScene.exitScene();
            this.dispatchEventWithData(SceneManagerEvent.EXITING_SCENE, this._currentScene);
        }
    }
    /**
    * 进入场景回调
    */
    private onSceneEntered(scene: IScene): void {
        if (this._nextScene == scene) {
            this._nextScene.state = SceneState.RUNNING;
            this.dispatchEventWithData(SceneManagerEvent.ENTER_SCENE, this._nextScene);
            this._currentScene = this._nextScene;
            this._nextScene = null;
        }
    }

    /**
     * 离开场景回调
     */
    private onSceneExited(scene: IScene): void {
        if (this._currentScene == scene) {
            this._currentScene.state = SceneState.IDLE;
            this.dispatchEventWithData(SceneManagerEvent.EXIT_SCENE, this._currentScene);
            this.enterNextScene();
        }
    }
    /**
   * 进入下一场景
   */
    private enterNextScene(): void {
        if (this._nextScene == null) {
            return;
        }
        this._nextScene.state = SceneState.ENTERING;
        this._nextScene.enterScene();
        this.dispatchEventWithData(SceneManagerEvent.ENTERING_SCENE, this._nextScene);
    }

    /**
     * 对象池派发事件
     */
    public dispatchEventWithData(type: string, scene: IScene): void {
        EventMgr.emit(type, scene);
    }
}